package com.kitty.game.task.service.taskHandler;

import com.kitty.common.thread.IdGenerator;
import com.kitty.common.utils.SpringUtils;
import com.kitty.game.activity.ActivityDataPool;
import com.kitty.game.activity.model.product.ActivityType;
import com.kitty.game.activity.model.product.DugeonSet;
import com.kitty.game.activity.model.user.Dugeon;
import com.kitty.game.config.NPC;
import com.kitty.game.config.TaskSet;
import com.kitty.game.confirm.model.CancelDugeonConfirm;
import com.kitty.game.confirm.model.CreateDugeonConfirm;
import com.kitty.game.enter.ReqTelePort;
import com.kitty.game.i18n.I18nId;
import com.kitty.game.i18n.I18nIdDataPool;
import com.kitty.game.map.MapDataPool;
import com.kitty.game.npc.service.NewNpcService;
import com.kitty.game.role.model.Role;
import com.kitty.game.task.message.vo.TaskInfo;
import com.kitty.game.task.model.product.TaskTarget;
import com.kitty.game.task.model.product.TaskType;
import com.kitty.game.task.service.NewTaskService;
import com.kitty.game.task.service.targetHandler.TaskTargetHelper;
import com.kitty.game.team.message.RespConfirm;
import com.kitty.game.team.message.RespMsg;
import com.kitty.game.team.model.Member;
import com.kitty.game.team.model.Team;
import com.kitty.game.team.service.TeamService;
import com.kitty.game.tongtianta.BallotInfo;
import com.kitty.game.tongtianta.RespBallotResult;
import com.kitty.game.tongtianta.RespTeamBallot;
import com.kitty.game.utils.*;
import com.kitty.game.welfare.model.CommonFetchedData;
import com.kitty.listener.event.FightEndEvent;
import com.kitty.mina.cache.DataCache;
import com.kitty.mina.message.MessagePusher;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.text.MessageFormat;
import java.util.*;

/**
 * 副本任务处理类
 */
@Component
public class DugeonTaskHandler extends TimeTaskHandler {
    @Autowired
    TeamService teamService;
    @Autowired
    NewNpcService npcService;
    @Autowired
    NewTaskService taskService;

    /**
     * 第一个任务ID
     */
    private static final int FIRST_TASK_ID = 120;
    /**
     * 任务奖励的ID
     */
    private static final int REWARD_TASK_ID = 125;
    /**
     * 创建副本最少组队人数
     */
    private static final int MIN_TEAM_COUNT = 1;
    /**
     * 创建副本的最小等级
     */
    private static final int MIN_LEVEL = 30;
    /**
     * 队员之间最大等级差
     */
    private static final int MAX_LEVEL_DIFF = 10;
    private static final String DUGEON_NAME = "飘渺仙府";

    private static final int DUGEON_ENTER_MAPID = 27008;
    private static final int DUGEON_ENTER_X = 23;
    private static final int DUGEON_ENTER_Y = 25;

    private static final int DUGEON_EXIT_MAPID = 5000;
    private static final int DUGEON_EXIT_X = 140;
    private static final int DUGEON_EXIT_Y = 16;

    /**
     * 副本地图
     */
    private static final List<Integer> DEGEON_MAP = Arrays.asList(27008, 25008, 25009);

    /**创建副本需要的金钱*/
    private int createNeedMoney = 1000000;
    /**副本任务持续分钟数*/
    private int dugeonTaskMinute = 120;

    @Override
    public TaskType getTaskType() {
        return TaskType.DUGEON;
    }

    @PostConstruct
    public void init() {
        for (int mapId : DEGEON_MAP) {
            /**副本ID一致在副本中才能相互看到*/
            MapDataPool.MAP_KEY_GENERATERS.put(mapId, role -> DataCache.ROLE_DUGEON.getOrDefault(role.getUid(), 0L));
        }
    }

    public void loadCommonSet(Map<String, String> commonSetMap) {
        DugeonSet dugeonSet = Json.fromJson(DugeonSet.class, commonSetMap.get("dugeon_set"));
        if (dugeonSet != null) {
            ActivityDataPool.dugeonSet = dugeonSet;
        }
    }

    public void loadCommon() {
        Dao dao = SpringUtils.getBean(Dao.class);
        CommonFetchedData  dugeonDatas = dao.fetch(CommonFetchedData.class, CommonConst.dugeon_datas);
        //CommonFetchedData  roleOfflineData = dao.fetch(RoleOfflineData.class, "dugeon_datas");
        if (dugeonDatas != null) {
            Map<Long, Dugeon> dugeonMap = JsonUtils.string2Map(dugeonDatas.getData(), Long.class, Dugeon.class);
            if (dugeonMap != null) {
                for (Dugeon dugeon : dugeonMap.values()) {
                    if (dugeon.isOverTime()) {continue;}
                    DataCache.DUGEON_MAP.put(dugeon.getId(), dugeon);

                    for (long uid : dugeon.getMemberList()) {
                        DataCache.ROLE_DUGEON.put(uid, dugeon.getId());
                    }
                }
            }
        }
    }

    @PreDestroy
    private void shutDown() {
        saveCommon();
    }

    private void saveCommon() {
        Dao dao = SpringUtils.getBean(Dao.class);
        String data = JsonUtils.map2String(DataCache.DUGEON_MAP);
        dao.insertOrUpdate(new CommonFetchedData("dugeon_datas", data));
    }

    /**
     * 进入副本按钮
     * 包括创建副本后进入副本和直接进入副本
     */
    public void chooseEnterDugeon(Role role, NPC npc) {
        /**不是副本成员，则执行创建副本逻辑*/
        /**是副本成员，则执行进入副本逻辑*/
        if (isDugeonMember(role)) {
            enterDugeon(role, npc);
        } else {
            createDugeonAndBallot(role, npc);
        }
    }

    /**
     * 检测能否创建副本，并发起创建副本投票
     */
    private void createDugeonAndBallot(Role role, NPC npc) {
        String check = checkCreateDugeon(role);
        if (check != null) {
            SpringUtils.getNpcService().sendNpcContent(role, npc, check);
            return ;
        }
        /**发起投票*/
        createDugeonBallot(role);

    }

    /**
     * 检测能否创建副本
     */
    private String checkCreateDugeon(Role role) {
        if (!teamService.isTeamLeader(role)) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1500);
        }
        String names = teamService.checkMember(role, memberRole -> isDugeonMember(memberRole));
        if (names != null) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1511, names);
        }
        Team team = teamService.getTeam(role.getRoleId());
        names = teamService.getNotInTeam(team);
        if (names != null) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1510, names);
        }
        names = teamService.checkMember(role, memberRole -> !SpringUtils.getActivityService().isHaveRemainCount(role, ActivityType.DUGEON_TASK));
        if (names != null) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1533, names);
        }
        for (Member member : team.getList()) {
            if (member == null) {
                continue;
            }
            /**暂离的不用判断*/
            if (member.isInTeam() == false) {
                continue;
            }

            Role memberRole = SpringUtils.getRoleService().getOnlinePlayer(member.getRoleId());
            if (memberRole == null) {
                continue;
            }
            if (!SpringUtils.getActivityService().isHaveRemainCount(memberRole, ActivityType.DUGEON_TASK)){
                return I18nIdDataPool.getI18nContent(I18nId.PMT_1533, memberRole.getName());
            }
        }
        names = teamService.checkMember(team, memberRole -> teamService.checkMember(team, mRole -> memberRole.getLevel() - mRole.getLevel() > MAX_LEVEL_DIFF) != null);
        if (names != null) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1536, MAX_LEVEL_DIFF);
        }

        if (role.getLevel() < MIN_LEVEL) {
            MessagePusher.notify2Player(role, I18nId.PMT_1522, MIN_LEVEL);
            return "";
        }
        if (teamService.getTeamCount(role) < MIN_TEAM_COUNT) {
            MessagePusher.notify2Player(role, I18nId.PMT_1501, DUGEON_NAME, MIN_TEAM_COUNT);
            return "";
        }
        names = teamService.checkMember(role, memberRole -> memberRole.getLevel() < MIN_LEVEL);
        if (names != null) {
            MessagePusher.notify2Player(role, I18nId.PMT_1523, names, MIN_LEVEL);
            return "";
        }
        names = teamService.checkMember(role, memberRole -> memberRole.getActivity().isDugeonReward());
        if (names != null) {
            MessagePusher.notify2Player(role, I18nId.PMT_1524, names);
            return "";
        }
        names = teamService.checkMember(role, memberRole -> memberRole.getMoney() < createNeedMoney);
        if (names != null) {
            MessagePusher.notify2Player(role, I18nId.PMT_1526, names);
            return "";
        }

        return null;
    }

    private void enterDugeon(Role role, NPC npc) {
        String check = checkEnterDugeon(role);
        if (check != null) {
            SpringUtils.getNpcService().sendNpcContent(role, npc, check);
            return ;
        }

        doEnterDugeon(role);
    }

    /**
     * 是否副本成员
     */
    private boolean isDugeonMember(Role role) {
        if (role == null) {return false;}
        return DataCache.ROLE_DUGEON.containsKey(role.getUid());
    }

    /**
     * 是否副本创建者
     */
    private boolean isDugeonCreator(Role role) {
        if (role == null) {return false;}

        long dugeonId = DataCache.ROLE_DUGEON.getOrDefault(role.getUid(), 0L);
        Dugeon dugeon = DataCache.DUGEON_MAP.get(dugeonId);
        if (dugeon != null) {
            return dugeon.isCreator(role.getUid());
        }
        return false;
    }

    /**
     * 发起创建副本投票
     */
    public void createDugeonBallot(Role role) {
        int needMony = createNeedMoney;
        if (role.getMoney() < needMony) {
            MessagePusher.notify2Player(role, I18nId.PMT_1505);
            return ;
        }

        if (teamService.isTeamLeader(role)) {
            Map<Integer, Short> ballotResults = new HashMap<>();
            role.setConfirm(new CreateDugeonConfirm(ballotResults));

            /**队伍成员均初始为未操作*/
            teamService.memberHandle(role, memberRole -> ballotResults.put(memberRole.getRoleId(), Const.BALLOT_TYPE_UN_OP));

            /**队长发起，设置同意*/
            ballotResults.put(role.getRoleId(), Const.BALLOT_TYPE_AGREEN);

            /**给所有人发起投票界面*/
            RespTeamBallot respTeamBallot = new RespTeamBallot();
            respTeamBallot.setTeamLeader(teamService.isTeamLeader(role));
            String msg = I18nIdDataPool.getI18nContent(I18nId.PMT_1506, AsktaoUtil.getMoneyFormat(needMony), DUGEON_NAME);
            respTeamBallot.setMsg(msg);
            respTeamBallot.setCurrTime(new Long(new Date().getTime() / 1000).intValue() + 30);
            String title = I18nIdDataPool.getI18nContent(I18nId.PMT_1507);
            respTeamBallot.setTitle(title);
            teamService.pushMessage(role, respTeamBallot);

            ArrayList<BallotInfo> ballotInfos = new ArrayList<>();
            BallotInfo ballotInfo = new BallotInfo();
            ballotInfo.setName(role.getName());
            ballotInfo.setType((short) 1);
            ballotInfos.add(ballotInfo);
            RespBallotResult respBallotResult = new RespBallotResult();
            respBallotResult.setMeTime((short) -1);
            respBallotResult.setResultList(ballotInfos);
            teamService.pushMessage(role, respBallotResult);
            Team team = teamService.getTeam(role.getRoleId());
            createBugeonBallotAgree(role);
            fixedTeamAutoAgreen(role,team);
        }

    }

    /**
     * 投票。固定队开启自动同意投票
     */
    public void fixedTeamAutoAgreen(Role LeaderRole,Team team){
        //取队长固定队ID
        String fixedTeamId = LeaderRole.getFixedTeam();
        if(StringUtils.isNotEmpty(fixedTeamId)){
            for (Member member : team.getList()) {
                Role memberRole = SpringUtils.getRoleService().getOnlinePlayer(member.getUid());
                if(!teamService.isTeamLeader(member.getRoleId())){
                    //如果是一个固定队
                    if(fixedTeamId.equals(memberRole.getFixedTeam())){
                        //自动同意
                        createBugeonBallotAgree(memberRole);
                        MessagePusher.pushMessage(memberRole, new RespMsg("你开启了固定队伍特权1，参与副本#R投票#n自动通过"));

                    }
                }
            }
        }

    }
    /**
     * 创建副本投票不同意
     */
    public void createBugeonBallotDisagree(Role role) {
        Team team = teamService.getTeam(role.getRoleId());
        Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
        CreateDugeonConfirm createDugeonConfirm = (CreateDugeonConfirm)leaderRole.getConfirm();
        Map<Integer, Short> ballotResults = createDugeonConfirm.getBallotResults();
        ballotResults.put(role.getRoleId(), Const.BALLOT_TYPE_DISAGREE);

        RespBallotResult respBallotResult = getRespBallotResult(role);
        teamService.pushMessageToTeam(team, respBallotResult);

        if (isAllOp(ballotResults)) {
            teamService.memberHandle(team, memberRole -> npcService.closeDlg(memberRole, "DugeonVoteDlg"));
        }
    }


    /**获得投票结果*/
    private RespBallotResult getRespBallotResult(Role role) {
        Team team = teamService.getTeam(role.getRoleId());
        Map<Integer, Short> ballotResults = null;
        if (team.isLeader(role.getRoleId())) {
            CreateDugeonConfirm confirm = (CreateDugeonConfirm)role.getConfirm();
            ballotResults = confirm.getBallotResults();
        } else {
            Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
            CreateDugeonConfirm confirm = (CreateDugeonConfirm)leaderRole.getConfirm();
            ballotResults = confirm.getBallotResults();
        }

        ArrayList<BallotInfo> ballotInfos = new ArrayList<>();
        for (Map.Entry<Integer, Short> entry : ballotResults.entrySet()) {
            Role memberRole = SpringUtils.getRoleService().getOnlinePlayer(entry.getKey());
            if (memberRole == null) {continue;}
            BallotInfo ballotInfo = new BallotInfo();
            ballotInfo.setName(memberRole.getName());
            ballotInfo.setType(entry.getValue());
            ballotInfos.add(ballotInfo);
        }
        RespBallotResult respBallotResult = new RespBallotResult();
        respBallotResult.setMeTime((short) -1);
        respBallotResult.setResultList(ballotInfos);

        return respBallotResult;
    }

    /**
     * 创建副本投票同意
     */
    public void createBugeonBallotAgree(Role role) {
        Team team = teamService.getTeam(role.getRoleId());
        Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
        CreateDugeonConfirm createDugeonConfirm = (CreateDugeonConfirm)leaderRole.getConfirm();

        if (role.getMoney() < createNeedMoney) {
            MessagePusher.notify2Player(role, I18nId.PMT_1505);
            return ;
        }

        Map<Integer, Short> ballotResults = createDugeonConfirm.getBallotResults();
        ballotResults.put(role.getRoleId(), Const.BALLOT_TYPE_AGREEN);

        RespBallotResult respBallotResult = getRespBallotResult(role);
        teamService.pushMessageToTeam(team, respBallotResult);


        if (isAllOp(ballotResults)) {
            teamService.memberHandle(team, memberRole -> npcService.closeDlg(memberRole, "DugeonVoteDlg"));
        }

        /**所有人已经同意，则开始扣除*/
        boolean allAgree = true;
        for (short result : ballotResults.values()) {
            if (result != Const.BALLOT_TYPE_AGREEN) {
                allAgree = false;
            }
        }

        if (allAgree) {
            /**此时再检测下所有成员有足够的金钱*/
            String names = teamService.checkMember(team, memberRole -> memberRole.getMoney() < createNeedMoney);
            if (names != null) {
                teamService.memberHandle(team, memberRole -> MessagePusher.notify2Player(memberRole, I18nId.PMT_1508, names));
            } else {
                /**真正开始扣除*/
                teamService.memberHandleThreadLocal(team, memberRole -> SpringUtils.getRoleService().subtractMoney(role, createNeedMoney));
                /**创建副本*/
                createDugeon(team);

                /**接取任务*/
                TaskSet taskSet = SpringUtils.getTaskService().getTaskSet(FIRST_TASK_ID, role);
                teamService.memberHandleThreadLocal(team, memberRole -> acceptTask(memberRole, taskSet));

                /**进入副本*/
                doEnterDugeon(leaderRole);
            }
        }
    }

    /**是否队伍所有成员已经操作*/
    private boolean isAllOp(Map<Integer, Short> ballotResults) {
        boolean allOp = true;
        for (short result : ballotResults.values()) {
            if (result == Const.BALLOT_TYPE_UN_OP) {
                allOp = false;
            }
        }

        return allOp;
    }

    /**
     * 创建副本
     */
    private void createDugeon(Team team) {
        List<Long> memberList = new ArrayList<>();
        memberList.add(team.getLeaderUid());
        teamService.memberHandle(team, memberRole -> {
            if (!memberList.contains(memberRole.getUid())) {
                memberList.add(memberRole.getUid());
            }
        });

        Dugeon dugeon = new Dugeon(IdGenerator.getNextId(), memberList);
        DataCache.DUGEON_MAP.put(dugeon.getId(), dugeon);

        for (long uid : memberList) {
            DataCache.ROLE_DUGEON.put(uid, dugeon.getId());
        }
    }

    @Override
    public void doAfterSubmit(Role role, TaskSet taskSet) {
        super.doAfterSubmit(role, taskSet);
        /**每完成一个任务在接取下一任务后重置该任务*/
        doResetTask(role, taskSet);

        /**整组任务都完成时，则可以领取奖励*/
        if (getNextTask(role, taskSet) == null) {
            role.getActivity().setDugeonReward(true);
            role.save();
            /**显示奖励任务*/
            TaskSet rewardTaskSet = taskService.getTaskSet(REWARD_TASK_ID, role);
            taskService.pushTaskInfo(role, getTaskInfo(role, rewardTaskSet));

            /**增加完成次数*/
            SpringUtils.getActivityService().addFinishCount(role, ActivityType.DUGEON_TASK, 1);

            /**删除副本数据*/
            if (teamService.isTeamLeader(role)) {
                deleteDugeon(getDugeon(role));
                /**离开副本地图*/
                if (isInDugeon(role)) {
                    leaveDegeon(role);
                }
            }
        }
    }

    private boolean isAcceptedTask(Role role) {
        return getTaskSetByType(role) != null;
    }

    private String checkEnterDugeon(Role role) {
        String names = teamService.checkMember(role, memberRole -> !isAcceptedTask(memberRole));
        if (names != null) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1517, names);
        }
        names = teamService.checkMember(role, memberRole -> !SpringUtils.getActivityService().isHaveRemainCount(role, ActivityType.DUGEON_TASK));
        if (names != null) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1533, names);
        }

        Team team = teamService.getTeam(role.getRoleId());
        names = teamService.checkMember(team, memberRole -> teamService.checkMember(team, mRole -> memberRole.getLevel() - mRole.getLevel() > MAX_LEVEL_DIFF) != null);
        if (names != null) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1536, MAX_LEVEL_DIFF);
        }
        for (Member member : team.getList()) {
            if (member == null) {
                continue;
            }
            /**暂离的不用判断*/
            if (member.isInTeam() == false) {
                continue;
            }

            Role memberRole = SpringUtils.getRoleService().getOnlinePlayer(member.getRoleId());
            if (memberRole == null) {
                continue;
            }
            if (!SpringUtils.getActivityService().isHaveRemainCount(memberRole, ActivityType.DUGEON_TASK)){
                return I18nIdDataPool.getI18nContent(I18nId.PMT_1533, memberRole.getName());
            }
        }
        return null;
    }

    private void doEnterDugeon(Role role) {
        ReqTelePort reqTelePort = new ReqTelePort();
        reqTelePort.setMapId(DUGEON_ENTER_MAPID);
        reqTelePort.setX(DUGEON_ENTER_X);
        reqTelePort.setY(DUGEON_ENTER_Y);
        SpringUtils.getMapService().changeMap(role, reqTelePort);


        if (teamService.isInTeam(role)) {
            Team team = teamService.getTeam(role.getRoleId());
            teamService.memberHandle(team, memberRole -> {
                MessagePusher.notify2Player(memberRole, I18nId.PMT_1503, DUGEON_NAME);
            });
        }
    }

    public void startFight(Role role, NPC npc) {
        /**判断是否可以战斗*/
        String content = getNpcContentNotFight(role, npc);
        if (content != null) {
            npcService.sendNpcContent(role, npc, content);
            return ;
        }

        TaskSet taskSet = getTaskSetByType(role);
        TaskTarget taskTarget = taskService.getRoleDoingTaskTarget(role, taskSet);
        /**任务目标都完成时，可能获得null*/
        if (taskTarget == null) {
            return ;
        }

        TaskTargetHelper.INSTANCE.getTargetHandler(taskTarget.getTaskTargetType()).triggerNow(role, taskSet, taskTarget);
    }

    private String getNpcContentNotFight(Role role, NPC npc) {
        if (teamService.getTeamCount(role) < MIN_TEAM_COUNT) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1502, MIN_TEAM_COUNT);
        }

        return null;
    }

    /**
     * 客户端在任务界面点击离开副本
     */
    public void leaveDegeon(Role role) {
        SpringUtils.getMapService().changeMap(role, DUGEON_EXIT_MAPID,  DUGEON_EXIT_X, DUGEON_EXIT_Y);
    }

    @Override
    public void handleHeartBeat(Role role, long prevHeartTime) {
        TaskSet taskSet = getTaskSetByType(role);
        if (taskSet != null) {
            if (!isDugeonMember(role)) {
                forceResetTask(role, taskSet);
                MessagePusher.notifyMiscEx2Player(role, I18nId.PMT_1521, DUGEON_NAME);
            } else {
                taskService.pushTaskInfo(role, getTaskInfo(role, taskSet));
            }
        }
    }

    @Override
    public void handleLogin(Role role) {
        super.handleLogin(role);
        /**登录时如果在副本且不在战斗中(避免出现战斗重连时出现在副本外)，则退出副本*/
        if (isInDugeon(role) && SpringUtils.getFightService().isInFight(role) == false) {
            leaveDegeon(role);
        }

        /**登录时发现有副本任务，但无副本数据时删除副本任务*/
        if (isAcceptedTask(role) && getDugeon(role) == null) {
            TaskSet taskSet = getTaskSetByType(role);
            forceResetTask(role, taskSet);
        }

        /**登录时有奖励未领取显示奖励任务*/
        if (role.getActivity().isDugeonReward()) {
            /**显示奖励任务*/
            TaskSet rewardTaskSet = taskService.getTaskSet(REWARD_TASK_ID, role);
            taskService.pushTaskInfo(role, getTaskInfo(role, rewardTaskSet));
        }
    }

    /**
     * 是否在副本
     */
    public boolean isInDugeon(Role role) {
        if (role == null) {return false;}
        return DEGEON_MAP.contains(role.getPos().getMapId());
    }

    /**
     * 取消副本
     */
    public void cancelDugeon(Role role, NPC npc) {
        if (isDugeonMember(role)) {
            role.setConfirm(new CancelDugeonConfirm());

            String msg = isDugeonCreator(role) ? I18nIdDataPool.getI18nContent(I18nId.PMT_1515) : I18nIdDataPool.getI18nContent(I18nId.PMT_1519);
            RespConfirm respConfirm = new RespConfirm();
            respConfirm.setTips(msg);
            MessagePusher.pushMessage(role, respConfirm);
        }
    }

    /**
     * 确认取消副本
     */
    public void confirmCancelDugeon(Role role) {
        if (isDugeonMember(role)) {
            if (isDugeonCreator(role)) {
                /**创建者取消时，所有成员的副本任务也消失。同时副本数据删除*/
                Dugeon dugeon = getDugeon(role);
                deleteDugeon(dugeon);

                Role memberRole = null;
                for (long uid : dugeon.getMemberList()) {
                    memberRole = SpringUtils.getRoleService().getOnlinePlayer(uid);
                    if (memberRole == null) {continue;}
                    deleteTaskAndLeave(memberRole);
                    MessagePusher.notifyMiscEx2Player(memberRole, I18nId.PMT_1513, DUGEON_NAME);
                }
            } else {
                /**成员取消时，只取消任务*/
                deleteTaskAndLeave(role);
                /**离开队伍*/
                teamService.leave(role ,false);
                MessagePusher.notifyMiscEx2Player(role, I18nId.PMT_1520, DUGEON_NAME);
            }
        }
    }

    /**删除副本数据*/
    private void deleteDugeon(Dugeon dugeon) {
        DataCache.DUGEON_MAP.remove(dugeon.getId());
        for (long uid : dugeon.getMemberList()) {
            DataCache.ROLE_DUGEON.remove(uid);
        }
    }

    private void deleteTaskAndLeave(Role role) {
        if (role == null) {return ;}

        TaskSet taskSet = getTaskSetByType(role);
        if (taskSet == null) {return ;}

        forceResetTask(role, taskSet);
        /**离开副本地图*/
        if (isInDugeon(role)) {
            leaveDegeon(role);
        }
    }

    /**
     * 获得副本
     */
    public Dugeon getDugeon(Role role) {
        Long dugeonId = DataCache.ROLE_DUGEON.getOrDefault(role.getUid(), 0L);
        if (dugeonId > 0) {
            return DataCache.DUGEON_MAP.get(dugeonId);
        }
        return null;
    }

    @Override
    public TaskInfo getTaskInfo(Role role, TaskSet taskSet) {
        TaskInfo taskInfo = taskService.getTaskInfo(role, taskSet);
        long endTime = getDugeonEndTime(role);
        if (endTime > 0) {
            taskInfo.setTask_end_time((int) (endTime / TimeUtil.ONE_SECOND));
            taskInfo.setRefresh((short) 1);
            int remainMinute = (int) ((endTime - System.currentTimeMillis()) / TimeUtil.ONE_MINUTE);
            taskInfo.setTaskInfo(MessageFormat.format(taskInfo.getTaskInfo(), remainMinute));
        }

        return taskInfo;
    }

    /**
     * 获得副本结束时间
     */
    private long getDugeonEndTime(Role role) {
        Dugeon dugeon = getDugeon(role);
        return dugeon != null ? dugeon.getEndTime() : 0;
    }

    /**
     * 领取副本奖励
     */
    public void fetchReward(Role role, NPC npc) {
        String check = checkFetchReward(role);
        if (check != null) {
            SpringUtils.getNpcService().sendNpcContent(role, npc, check);
            return ;
        }

        String content = I18nIdDataPool.getI18nContent(I18nId.PMT_1532);
        SpringUtils.getNpcService().sendNpcContent(role, npc, content);
    }

    /**
     * 确认放弃任务
     */
    public void confirmGiveUpTask(Role role) {
        if (isDugeonCreator(role)) {
            cancelDugeon(role, null);
        } else {
            confirmCancelDugeon(role);
        }
    }

    /**
     * 是否可以组队
     */
    public boolean isCanTeam(Role role, Role otherRole) {
        if (role == null || otherRole == null) {return false;}
        if (isInDugeon(role) || isInDugeon(otherRole)) {
            long roleDugeonId = DataCache.ROLE_DUGEON.getOrDefault(role.getUid(), 0L);
            long otherDugeonId = DataCache.ROLE_DUGEON.getOrDefault(otherRole.getUid(), 0L);
            return roleDugeonId == otherDugeonId;
        }
        return true;
    }

    /**是否可以申请组队*/
    public boolean isRequestJoinTeam(Role role, Team team) {
        Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
        if (!isCanTeam(role, leaderRole)) {
            if (isInDugeon(role)) {
                MessagePusher.notify2Player(role, I18nId.PMT_1529);
            } else {
                MessagePusher.pushMessage(role, new RespMsg("对方所在地图无法接受申请。"));
            }
            return false;
        }

        return true;
    }

    /**是否可以邀请组队*/
    public boolean isInviteJoinTeam(Role role, int inviteRoleId) {
        Role invitRole = SpringUtils.getRoleService().getOnlinePlayer(inviteRoleId);
        if (!isCanTeam(role, invitRole)) {
            if (isInDugeon(role)) {
                MessagePusher.notify2Player(role, I18nId.PMT_1530);
            } else {
                MessagePusher.pushMessage(role, new RespMsg("对方所在地图无法接受邀请。"));
            }

            return false;
        }

        return true;
    }

    public boolean isAcceptJoinTeam(Role role, int joinRoleId) {
        Role joinRole = SpringUtils.getRoleService().getOnlinePlayer(joinRoleId);
        if (!isCanTeam(role, joinRole)) {
            if (isInDugeon(role)) {
                MessagePusher.notify2Player(role, I18nId.PMT_1531);
            } else {
                MessagePusher.pushMessage(role, new RespMsg("对方所在地图无法接受操作。"));
            }

            return false;
        }

        return true;
    }

    /**是否可以归队*/
    public boolean isBackToTeam(Team team, Role memberRole) {
        /**队长在通天塔时，队员也需要在与队长同一层时才能归队*/
        Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
        if (!isCanTeam(leaderRole, memberRole)) {
            if (isInDugeon(leaderRole)) {
                MessagePusher.notify2Player(memberRole, I18nId.PMT_1527);
            } else {
                MessagePusher.pushMessage(memberRole, new RespMsg("本地图无法直接进入。"));
            }
            return false;
        }
        return true;
    }

    /**
     * 领取经验奖励
     */
    public void fetchExpReward(Role role, NPC npc) {
        boolean canFetch = doBeforeFetchReward(role, npc);
        if (canFetch) {
            int exp = ActivityDataPool.dugeonSet.getExpReward() * role.getLevel();
            SpringUtils.getRoleService().addExp(role, exp, role.getLevel(), role.getPetBox().getFightPetId());
        }
    }

    /**
     * 领取道行奖励
     */
    public void fetchTaoReward(Role role, NPC npc) {
        boolean canFetch = doBeforeFetchReward(role, npc);
        if (canFetch) {
            int tao = ActivityDataPool.dugeonSet.getTaoReward();
            SpringUtils.getRoleService().addTao(role, tao);

            int matiral = ActivityDataPool.dugeonSet.getMatiralReward();
            SpringUtils.getRoleService().addFightMatiral(role, matiral);
        }
    }

    /**
     * 领取潜能奖励
     */
    public void fetchPotReward(Role role, NPC npc) {
        boolean canFetch = doBeforeFetchReward(role, npc);
        if (canFetch) {
            int pot = ActivityDataPool.dugeonSet.getPotReward() * role.getLevel();
            SpringUtils.getRoleService().addPot(role, pot);
        }
    }

    private String checkFetchReward(Role role) {
        if (!role.getActivity().isDugeonReward()) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1525);
        }
        return null;
    }

    private boolean doBeforeFetchReward(Role role, NPC npc) {
        String check = checkFetchReward(role);
        if (check != null) {
            SpringUtils.getNpcService().sendNpcContent(role, npc, check);
            return false;
        }

        role.getActivity().setDugeonReward(false);
        role.save();
        /**不再显示奖励任务*/
        TaskSet rewardTaskSet = taskService.getTaskSet(REWARD_TASK_ID, role);
        taskService.pushEndTask(role, rewardTaskSet.getTaskName());

        return true;
    }

    public String getCancelButton(Role role) {
        if (isAcceptedTask(role)) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1534);
        }
        return null;
    }

    public String getRewardButton(Role role) {
        if (role.getActivity().isDugeonReward()) {
            return I18nIdDataPool.getI18nContent(I18nId.PMT_1535);
        }
        return null;
    }

    /**
     * 检测副本是否过期
     */
    public void checkDugeon() {
        Collection<Dugeon> dugeons = DataCache.DUGEON_MAP.values();
        for (Dugeon dugeon : dugeons) {
            if (dugeon.isOverTime()) {
                deleteDugeon(dugeon);
                deleteMemberTaskAndLeave(dugeon);
            }
        }
    }

    private void deleteMemberTaskAndLeave(Dugeon dugeon) {
        if (dugeon == null) {return ;}

        Role role = null;
        for (long uid : dugeon.getMemberList()) {
            role = SpringUtils.getRoleService().getOnlinePlayer(uid);
            if (role == null) {continue;}
            deleteTaskAndLeave(role);
        }
    }

    @Override
    public void doFightFail(Role role, FightEndEvent fightEndEvent) {
        super.doFightFail(role, fightEndEvent);

        if (isInDugeon(role) && teamService.isTeamLeader(role)) {
            teamService.memberHandleThreadLocal(role, memberRole -> SpringUtils.getRoleService().punishFightDead(memberRole));
        }
    }
}